package com.yungu.swift.order.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.yungu.swift.assets.driver.model.vo.DriverVo;
import com.yungu.swift.assets.driver.service.DriverService;
import com.yungu.swift.assets.passenger.model.dto.PassengerCouponDto;
import com.yungu.swift.assets.passenger.model.dto.PassengerRechargeCityDto;
import com.yungu.swift.assets.passenger.model.dto.PassengerRechargeDto;
import com.yungu.swift.assets.passenger.model.param.ApiPasPayCouponParam;
import com.yungu.swift.assets.passenger.model.vo.PassengerVo;
import com.yungu.swift.assets.passenger.service.PassengerCouponService;
import com.yungu.swift.assets.passenger.service.PassengerRechargeCityService;
import com.yungu.swift.assets.passenger.service.PassengerRechargeService;
import com.yungu.swift.assets.passenger.service.PassengerService;
import com.yungu.swift.autoconfig.redis.RedisCacheService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.SpringContextHolder;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.constants.OrderConstant;
import com.yungu.swift.constants.PassengerConstant;
import com.yungu.swift.order.config.NacosListener;
import com.yungu.swift.order.consts.Constants;
import com.yungu.swift.order.helper.OrderHelper;
import com.yungu.swift.order.model.dto.OrderDto;
import com.yungu.swift.order.model.dto.OrderFareDto;
import com.yungu.swift.order.model.dto.OrderRechargeDto;
import com.yungu.swift.order.model.vo.PayVo;
import com.yungu.swift.order.processor.CommissionProcessor;
import com.yungu.swift.order.processor.PassengerGiftProcessor;
import com.yungu.swift.order.processor.PayProcessor;
import com.yungu.swift.order.processor.PayProcessorFactory;
import com.yungu.swift.order.service.OrderFareService;
import com.yungu.swift.order.service.OrderRechargeService;
import com.yungu.swift.order.service.OrderService;
import com.yungu.swift.order.service.PayService;
import com.yungu.swift.order.utils.PayDataBuilder;
import com.yungu.swift.order.utils.PayLogBuilder;
import com.yungu.swift.order.utils.PayVerifySignUtils;
import com.yungu.swift.socket.communication.message.UploadLocationMessage;
import com.yungu.swift.socket.communication.service.UploadLocationService;
import com.yungu.swift.socket.push.model.PushContent;
import com.yungu.swift.socket.push.service.PushService;
import com.yungu.swift.system.finance.model.dto.FinancePrepayDto;
import com.yungu.swift.system.finance.service.FinancePrepayService;
import com.yungu.swift.system.sys.model.vo.SysDriverAccountVo;
import com.yungu.swift.system.sys.model.vo.SysPassengerAccountVo;
import com.yungu.swift.system.sys.service.SysAccountDriverService;
import com.yungu.swift.system.sys.service.SysAccountPassengerService;
import com.yungu.swift.system.sys.service.SysCityService;
import com.yungu.swift.utils.JsonUtils;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import static com.yungu.swift.order.model.enums.OrderErrorEnum.ERR_CODE_DOUBLE_PAY;
import static com.yungu.swift.order.model.enums.OrderErrorEnum.ERR_CODE_HAD_PAID;

/**
 * Copyright © 厦门云谷互联信息科技有限公司 2018-2020 All Right Reserved
 * <p>
 * 支付业务逻辑接口实现类
 *
 * @author Zerrion
 * @version 1.0.0-RELEASE
 * @since 2018-07-05 10:29
 */
@Service
public class PayServiceImpl implements PayService {
    private static final Logger logger = LoggerFactory.getLogger(PayServiceImpl.class);

    @Autowired
    private RedisCacheService redisCacheService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderFareService orderFareService;
    @Autowired
    private OrderRechargeService orderRechargeService;
    @Autowired
    private CommissionProcessor commissionProcessor;

    @Reference
    private DriverService driverService;
    @Reference
    private PassengerService passengerService;
    @Reference
    private PassengerCouponService passengerCouponService;
    @Reference
    private FinancePrepayService financePrepayService;
    @Reference
    private PushService pushService;
    @Reference
    private PassengerRechargeService passengerRechargeService;
    @Reference
    private PassengerRechargeCityService passengerRechargeCityService;
    @Reference
    private UploadLocationService uploadLocationService;
    @Reference
    private SysAccountPassengerService sysAccountPassengerService;
    @Reference
    private SysAccountDriverService sysAccountDriverService;
    @Reference
    private SysCityService sysCityService;

    @Override
    public ResponseData<Map<String, String>> trade(PayVo payVo) {
        Map<String, Object> map = new HashMap<>(4);
        //初始化预支付入口日志
        PayLogBuilder.buildLog(payVo);
        logger.info("{} 预支付流程开始:{}", payVo.getDescription(), JsonUtils.toJSONString(payVo));
        //支付加锁
        if (payVo.getPayPurpose() == OrderConstant.PAY_PURPOSE_CHARGE_FARE) {
            //1.缓存校验 ---- 订单重复支付判断，无法插入缓存，则KEY已存在 -----
            logger.info("{}--尝试加入入口缓存锁", payVo.getDescription());
            boolean flag = redisCacheService.setIfAbsent(Constants.ORDER_CACHE_KEY + payVo.getOrderUuid(), payVo.getOrderUuid(), 5L);
            if (!flag) {
                logger.info("{}入口缓存锁判定发起重复支付", payVo.getDescription());
                return ResponseData.buildErrorResponse(ERR_CODE_DOUBLE_PAY.getCode(), ERR_CODE_DOUBLE_PAY.getMsg());
            }
            logger.info("{}--加入入口缓存锁成功", payVo.getDescription());

            //2.预支付校验 ---- 如果订单有已支付信息，返回已支付 ---
            map.put("orderUuid", payVo.getOrderUuid());
            map.put("status", 1);
            ResponseData<List<FinancePrepayDto>> financePrepayResponse = financePrepayService.list(map);
            if (financePrepayResponse.isSuccess() && CollectionUtils.isNotEmpty(financePrepayResponse.getData())) {
                logger.info("{}--预支付状态判定订单支付已完成，预支付流程结束", payVo.getDescription());
                removeLock(payVo);
                return ResponseData.buildErrorResponse(ERR_CODE_HAD_PAID.getCode(), ERR_CODE_HAD_PAID.getMsg());
            }
            logger.info(payVo.getDescription() + "--通过系统内部预支付校验，没有已支付的订单");
        }
        //3.订单状态校验 ----- 如果订单小状态不是待支付，返回订单状态异常 --------
        ResponseData<PayVo> validateBusiness = validateBusiness(payVo);
        if (!validateBusiness.isSuccess()) {
            logger.info("{}--{}", payVo.getDescription(), validateBusiness.getMsg());
            removeLock(payVo);
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "订单状态异常");
        }
        //4.计算应付金额
        ResponseData<PayVo> buildActualFare = buildActualFare(payVo);
        if (!buildActualFare.isSuccess()) {
            logger.info("{}--{}", payVo.getDescription(), buildActualFare.getMsg());
            removeLock(payVo);
            return ResponseData.buildErrorResponse(buildActualFare.getErrCode(), buildActualFare.getMsg());
        }
        PayLogBuilder.appendLog(payVo, String.format("--应付金额[ %s ]", payVo.getActualFare().toString()));

        //分支.系统余额支付
        if (payVo.getPayType() == OrderConstant.PAY_TYPE_BALANCE) {
            //判断余额是否足够支付
            if (payVo.getPayPurpose() == OrderConstant.PAY_PURPOSE_CHARGE_FARE) {
                BigDecimal balance = BigDecimal.ZERO;
                BigDecimal rechargeBalance;
                BigDecimal actualFare = payVo.getActualFare();
                if (payVo.getPaySide() == CommonConstant.PASSENGER) {
                    balance = Optional.ofNullable(payVo.getAccountPassengerBean().getPresentBalance()).orElse(BigDecimal.ZERO);
                    rechargeBalance = Optional.ofNullable(payVo.getAccountPassengerBean().getRechargeBalance()).orElse(BigDecimal.ZERO);
                    balance = balance.add(rechargeBalance);
                }
                if (payVo.getPaySide() == CommonConstant.DRIVER) {
                    balance = Optional.ofNullable(payVo.getAccountDriverBean().getCanFrowardBalance()).orElse(BigDecimal.ZERO);
                }
                if (balance.compareTo(actualFare) == -1) {
                    logger.info(payVo.getDescription() + "--账户余额不足");
                    removeLock(payVo);
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "账户余额不足");
                }
            }

            //余额处理入口日志
            logger.info(payVo.getDescription() + "--开始处理余额支付业务逻辑");
            ResponseData<String> processPay = PayProcessorFactory.processPay(payVo);
            logger.info(payVo.getDescription() + "--" + processPay.getMsg());
            if (!processPay.isSuccess()) {
                removeLock(payVo);
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "余额支付失败");
            }
            logger.info(payVo.getDescription() + "--余额支付业务逻辑处理完毕，预支付和整体支付流程结束");
            return ResponseData.buildSuccessResponse("支付成功", null);
        }

        //5.通过系统预支付信息判断是否已有"相同条件"的待支付订单，如有则直接返回
        FinancePrepayDto financePrepayDto = financePrepayService.findAvailablePrepay(payVo.getOrderUuid(),
                payVo.getPassengerCouponUuid(), payVo.getActualFare().doubleValue(), payVo.getPayType()).getData();
        if (financePrepayDto != null) {
            logger.info(payVo.getDescription() + "--找到相同条件预支付信息，直接返回，预支付流程结束");
            try {
                Map<String, String> tradeMap = JsonUtils.readValue(financePrepayDto.getTradeData(), Map.class);
                return ResponseData.buildSuccessResponse("第三方预支付请求成功", tradeMap);
            } catch (IOException e) {
                logger.error("JsonUtils.readValue error, orderUuid:{}", financePrepayDto.getOrderUuid());
            }
        }
        //如没有，则把原订单都设置为失效订单，并重新创建新的支付单
        financePrepayService.disablePaying(payVo.getOrderUuid());

        //6.创建第三方预支付信息
        //生成交易流水号
        payVo.setTradeNo(StringUtils.buildUUID());
        PayLogBuilder.appendLog(payVo, "--流水号[" + payVo.getTradeNo() + "]");


        ResponseData<Map<String, String>> buildPayData = ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "构建预支付失败", null);
        //请求第三方预支付
        if (payVo.getPayType() == OrderConstant.PAY_TYPE_TENPAY) {
            buildPayData = PayDataBuilder.buildTenPayData(payVo);
        }
        if (payVo.getPayType() == OrderConstant.PAY_TYPE_ALIPAY) {
            buildPayData = PayDataBuilder.buildAliPayData(payVo);
        }
        logger.info(payVo.getDescription() + "--" + buildPayData.getMsg());
        if (!buildPayData.isSuccess()) {
            removeLock(payVo);
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "构建预支付失败");
        }
        //7.创建系统内部预支付信息
        FinancePrepayDto saveFinancePrepayDto = new FinancePrepayDto();
        saveFinancePrepayDto.setUuid(StringUtils.buildUUID());
        saveFinancePrepayDto.setSerialNumber(payVo.getTradeNo());
        saveFinancePrepayDto.setOrderUuid(payVo.getOrderUuid());
        saveFinancePrepayDto.setCouponUuid(payVo.getPassengerCouponUuid());
        saveFinancePrepayDto.setType(payVo.getPayType());
        saveFinancePrepayDto.setSide(payVo.getPaySide());
        saveFinancePrepayDto.setPurpose(payVo.getPayPurpose());
        saveFinancePrepayDto.setStatus(FinancePrepayDto.STATUS_PREPAY);
//        saveFinancePrepayDto.setMoney(payVo.getActualFare().setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue());
        saveFinancePrepayDto.setMoney(payVo.getActualFare().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        saveFinancePrepayDto.setDescription(payVo.getDescription());
        saveFinancePrepayDto.setTradeData(JsonUtils.toJSONString(buildPayData.getData()));
        saveFinancePrepayDto.setCreateOn(new Date());
        saveFinancePrepayDto.setCreateBy(payVo.getUserUuid());
        saveFinancePrepayDto.setParams(payVo.toString());
        ResponseData<Boolean> addResData = financePrepayService.add(saveFinancePrepayDto);
        payVo.setFinancePrepayUuid(saveFinancePrepayDto.getUuid());
        if (!addResData.isSuccess()) {
            logger.info(payVo.getDescription() + "--" + "创建系统预支付信息失败");
            removeLock(payVo);
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "创建系统预支付信息失败");
        }
        logger.info("{}--创建系统预支付信息成功", payVo.getDescription());
        logger.info("{}--预支付流程完毕", payVo.getDescription());
        buildPayData.setMsg("第三方预支付请求成功");
        return buildPayData;
    }

    @Override
    public ResponseData<String> tradeCallback(int payType, Map<String, String> map) {
        String payTypeStr = "";
        if (payType == OrderConstant.PAY_TYPE_TENPAY) {
            payTypeStr = "[微信]";
        }
        if (payType == OrderConstant.PAY_TYPE_ALIPAY) {
            payTypeStr = "[支付宝]";
        }
        String tradeNo = map.get("out_trade_no");

        //回调入口日志
        logger.info("[第三方回调]" + payTypeStr + "--流水号[" + tradeNo + "]--开始处理回调");

        FinancePrepayDto financePrepayDto = financePrepayService.get(MapUtils.build("serialNumber", tradeNo)).getData();
        if (financePrepayDto == null) {
            logger.info("[第三方回调]" + payTypeStr + "--流水号[" + tradeNo + "]--获取不到预支付信息");
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到系统内部预支付信息");
        }

        PayVo payVo = null;
        try {
            payVo = JsonUtils.readValue(financePrepayDto.getParams(), PayVo.class);
            PayLogBuilder.prependLog(payVo, "[第三方回调]");
        } catch (IOException e) {
            e.printStackTrace();
        }

        //回调状态校验
        ResponseData<Boolean> callbackValidateStatus = callbackValidateStatus(payVo, map);
        if (!callbackValidateStatus.isSuccess() || Boolean.FALSE.equals(callbackValidateStatus.getData())) {
            logger.info("{}--{}", payVo.getDescription(), callbackValidateStatus.getMsg());
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, callbackValidateStatus.getMsg());
        }

        //验签
        ResponseData<String> callbackGetSignKey = callbackGetSignKey(payVo);
        if (!callbackGetSignKey.isSuccess() || Boolean.FALSE.equals(callbackGetSignKey.getData())) {
            logger.info("{}--{}", payVo.getDescription(), callbackGetSignKey.getMsg());
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, callbackGetSignKey.getMsg());
        }
        ResponseData<Boolean> callbackValidateSign = callbackValidateSign(payVo, map, callbackGetSignKey.getData());
        logger.info("99999999:{}",callbackValidateSign.getData());
        if (!callbackValidateSign.isSuccess() || Boolean.FALSE.equals(callbackValidateSign.getData())) {
            logger.info("{}--{}", payVo.getDescription(), callbackValidateSign.getMsg());
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "验签失败");
        }
        //第三方回调不执行操作人验证
        ResponseData<Boolean> processBusiness = processBusiness(financePrepayDto, payVo, null);
        if (!processBusiness.isSuccess() || Boolean.FALSE.equals(processBusiness.getData())) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "业务处理异常");
        }

        logger.info(payVo.getDescription() + "--第三方回调流程完毕--尝试清除入口缓存锁");
        removeLock(payVo.getOrderUuid());
        return ResponseData.buildSuccessResponse("第三方回调流程完毕", payVo.getOrderUuid());
    }

    @Override
    public ResponseData<String> invokeCallback(String orderUuid, String userUuid) {
        logger.info("[主动执行回调]--订单[" + orderUuid + "]--流程开始");
        Map<String, Object> map = new HashMap<>(5);
        map.put("orderUuid", orderUuid);
        FinancePrepayDto financePrepayDto = financePrepayService.get(map).getData();
        if (financePrepayDto == null) {
            logger.info("[主动执行回调]--订单[" + orderUuid + "]--获取不到预支付信息，流程结束");
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "[主动执行回调]--订单[" + orderUuid + "]--获取不到预支付信息，流程结束");
        }
        try {
            PayVo payVo = JsonUtils.readValue(financePrepayDto.getParams(), PayVo.class);
            PayLogBuilder.prependLog(payVo, "[主动执行回调]");
            ResponseData<Boolean> processBusiness = processBusiness(financePrepayDto, payVo, userUuid);
            if (!processBusiness.isSuccess()) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "处理回调业务异常");
            }
            logger.info(payVo.getDescription() + "--主动执行回调流程完毕--尝试清除入口缓存锁");
            removeLock(payVo.getOrderUuid());
            return ResponseData.buildSuccessResponse("主动执行回调流程成功", payVo.getOrderUuid());
        } catch (IOException e) {
            logger.error("解析预支付信息错误，预支付信息：{}", financePrepayDto.getParams(), e);
        }
        logger.info("--主动执行回调流程异常,orderUuid:{}", orderUuid);
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "主动执行回调流程失败");
    }

    private void removeLock(String orderUuid) {
        String cacheKey = Constants.ORDER_CACHE_KEY + orderUuid;
        if (redisCacheService.hasKey(cacheKey)) {
            redisCacheService.delete(cacheKey);
            logger.info(orderUuid + "--清除入口缓存锁成功");
        } else {
            logger.info(orderUuid + "--入口缓存锁不存在");
        }
    }

    /**
     * 通用处理系统内部业务逻辑
     *
     * @return
     */
    private ResponseData<Boolean> processBusiness(FinancePrepayDto financePrepayDto, PayVo payVo, String userUuid) {
        //设置回调开关，用于清除回调缓存锁
        payVo.setCallback(true);

        //判断预支付状态，只能是支付中
        if (financePrepayDto.getStatus() == FinancePrepayDto.STATUS_PAID) {
            logger.info("{}--预支付状态判定订单支付已完成，请勿重复支付", payVo.getDescription());
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "支付已完成，请勿重复支付");
        }
        if (financePrepayDto.getStatus() == FinancePrepayDto.STATUS_INVALID) {
            logger.info("{}--预支付状态判定订单已失效", payVo.getDescription());
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "订单已失效");
        }
        logger.info("{}--系统内部预支付状态验证通过", payVo.getDescription());

        //回调判定订单状态
        ResponseData<Boolean> validateBusinessCallback = validateBusinessCallback(payVo, userUuid);
        if (!validateBusinessCallback.isSuccess() || Boolean.FALSE.equals(validateBusinessCallback.getData())) {
            logger.info("{}--{}", payVo.getDescription(), validateBusinessCallback.getMsg());
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "回调订单状态异常");
        }
        logger.info(payVo.getDescription() + "--尝试加入回调缓存锁");
        boolean flag = redisCacheService.setIfAbsent(Constants.CALLBACK_CACHE_KEY + payVo.getOrderUuid(), payVo.getOrderUuid(), 5L);
        if (!flag) {
            logger.info(payVo.getDescription() + "--回调缓存锁判定发起重复回调");
            //只有重复支付不清除锁，其他情况下暴露业务错误
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "回调业务处理正在进行中，请勿重复回调");
        }
        logger.info(payVo.getDescription() + "--加入回调缓存锁成功");

        //处理业务表数据
        logger.info(payVo.getDescription() + "--开始处理业务表数据");
        ResponseData<String> processPay = PayProcessorFactory.processPay(payVo);
        if (!processPay.isSuccess()) {
            logger.info(payVo.getDescription() + "--" + processPay.getMsg());
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "处理业务表数据失败");
        }
        //回调缓存锁清除已在处理器中进行
        return ResponseData.buildSuccessResponse("业务逻辑处理完毕", Boolean.TRUE);
    }


    /**
     * 处理应付金额，其中包括优惠券全抵扣情况
     *
     * @return
     */
    private ResponseData<PayVo> buildActualFare(PayVo payVo) {
        //支付车费
        if (payVo.getPayPurpose() == OrderConstant.PAY_PURPOSE_CHARGE_FARE) {
            BigDecimal totalFare = BigDecimal.valueOf(payVo.getOrderFareDto().getTotalFare());
            BigDecimal actualDeductible = BigDecimal.ZERO;

            //优先处理应付金额为0的情况
            if (totalFare.compareTo(BigDecimal.ZERO) == 0) {
                payVo.setActualFare(BigDecimal.valueOf(0.01D));
                payVo.setActualDeductible(BigDecimal.ZERO);
                logger.info("订单：{}，应付金额为0，支付 0.01 元", payVo.getOrderUuid());
                return ResponseData.buildSuccessResponse("计算应付金额成功--应付金额[" + payVo.getActualFare() + "]", payVo);
            }

            payVo.setActualFare(totalFare);
            payVo.setActualDeductible(actualDeductible);

            //如果是司机支付，直接返回初始化后的值
            if (payVo.getPaySide() == CommonConstant.DRIVER) {
                return ResponseData.buildSuccessResponse("计算应付金额成功--应付金额[" + payVo.getActualFare() + "]", payVo);
            }

            //乘客和微信支付，继续执行流程
            if (StringUtils.isEmpty(payVo.getPassengerCouponUuid())) {
                return ResponseData.buildSuccessResponse("计算应付金额成功--无优惠券--应付金额[" + payVo.getActualFare().toString() + "]", payVo);
            }

            //------------------------------------------ 优惠券处理逻辑开始 --------------------------------------------
            //获取优惠券
            ApiPasPayCouponParam couponParam = new ApiPasPayCouponParam();
            couponParam.setCouponUuid(payVo.getPassengerCouponUuid());
            couponParam.setTotalFare(payVo.getOrderFareDto().getTotalFare());
            //没有返回错误情况，也不可能查不到优惠券，若有则是业务错误
            List<PassengerCouponDto> couponList = passengerCouponService.getPayCouponList(couponParam).getData();
            if (couponList != null && couponList.size() > 0) {
                //固定金额抵扣情况
                if (couponList.get(0).getMoney() != null) {
                    actualDeductible = BigDecimal.valueOf(couponList.get(0).getMoney());
                }
                //折扣金额情况
                else if (couponList.get(0).getDiscount() != null) {
                    BigDecimal discountNumber = BigDecimal.valueOf(couponList.get(0).getDiscount()).divide(BigDecimal.TEN, 1, BigDecimal.ROUND_HALF_UP);
                    BigDecimal discountAmount = totalFare.multiply(discountNumber);
//                    actualDeductible = totalFare.subtract(discountAmount).setScale(1, BigDecimal.ROUND_HALF_UP);
                    actualDeductible = totalFare.subtract(discountAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
                }
            }

            //重新计算应付金额和抵扣金额
//            BigDecimal actualFare = totalFare.subtract(actualDeductible).setScale(1, BigDecimal.ROUND_HALF_UP);
            BigDecimal actualFare = totalFare.subtract(actualDeductible).setScale(2, BigDecimal.ROUND_HALF_UP);

            //应付金额为负值时，属于优惠券完全抵扣情况，应付金额为0，抵扣金额为totalFare
            if (actualFare.compareTo(BigDecimal.ZERO) != 1) {
                payVo.setActualFare(BigDecimal.valueOf(0.01D));
                payVo.setActualDeductible(totalFare);
                logger.info("订单：{}，优惠券完全抵扣，支付 0.01 元", payVo.getOrderUuid());
                return ResponseData.buildSuccessResponse("计算应付金额成功--优惠券完全抵扣--应付金额[" + payVo.getActualFare().toString() + "]", payVo);
            }

            payVo.setActualFare(actualFare);
            payVo.setActualDeductible(actualDeductible);
            return ResponseData.buildSuccessResponse("计算应付金额成功--有优惠券--应付金额[" + payVo.getActualFare().toString() + "]--优惠券金额[" + payVo.getActualDeductible().toString() + "]", payVo);
        }
        //充值
        if (payVo.getPayPurpose() == OrderConstant.PAY_PURPOSE_RECHARGE_ACCOUNT) {
            payVo.setActualFare(BigDecimal.valueOf(payVo.getPassengerRechargeDto().getMoney()));
            return ResponseData.buildSuccessResponse("计算应付金额成功--充值金额[" + payVo.getActualFare() + "]", payVo);
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "计算应付金额失败--不合法的支付目的");
    }

    /**
     * 业务逻辑校验
     *
     * @return
     */
    private ResponseData<PayVo> validateBusiness(PayVo payVo) {
        //支付车费
        if (payVo.getPayPurpose() == OrderConstant.PAY_PURPOSE_CHARGE_FARE) {
            //获取订单
            OrderDto orderDto = orderService.get(payVo.getOrderUuid()).getData();
            if (orderDto == null) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到订单信息");
            }
            if (Objects.equals(orderDto.getSubStatus(), OrderConstant.ORDER_STATUS_COMPLETE)) {
                return ResponseData.buildErrorResponse(ERR_CODE_HAD_PAID.getCode(), ERR_CODE_HAD_PAID.getMsg());
            }
            if (orderDto.getTypeModule() == CommonConstant.BUSINESS_TYPE_POOL
                    || orderDto.getTypeModule() == CommonConstant.BUSINESS_TYPE_PARCEL) {
                List<Integer> statusList = Arrays.asList(100, 520, 530);
                if (!statusList.contains(orderDto.getJoinStatus())) {
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "订单状态判定订单状态异常，请联系管理员");
                }
            } else {
                if (!Constants.ORDER_PREPAY_SUB_STATUS.contains(orderDto.getSubStatus())) {
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "订单状态判定订单状态异常，请联系管理员");
                }
            }
            payVo.setOrderDto(orderDto);
            //操作人验证
            if (payVo.getPaySide() == CommonConstant.PASSENGER) {
                if (!payVo.getUserUuid().equals(orderDto.getPassengerUuid())) {
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "非发单乘客无操作权限");
                }
            }
            if (payVo.getPaySide() == CommonConstant.DRIVER) {
                if (!payVo.getUserUuid().equals(orderDto.getActualDriverUuid())) {
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "非实际接单司机无操作权限");
                }
            }
            //获取订单价格
            OrderFareDto orderFareDto = orderFareService.get(MapUtils.build("orderUuid", payVo.getOrderUuid())).getData();
            if (orderFareDto == null) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到订单价格信息");
            }
            payVo.setOrderFareDto(orderFareDto);
            //当非跨城业务支付的时候
            if (StringUtils.isNotEmpty(orderDto.getActualDriverUuid())) {
                //获取司机
                DriverVo driverVo = driverService.selInfo(orderDto.getActualDriverUuid()).getData();
                if (driverVo == null) {
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到司机信息");
                }
                payVo.setDriverVo(driverVo);
                // 获得司机账户
                ResponseData<SysDriverAccountVo> findAccountDriverVo = sysAccountDriverService.findAccountDriverVo(
                        MapUtils.build("uuid", orderDto.getActualDriverUuid()));
                if (findAccountDriverVo.isSuccess() && findAccountDriverVo.getData() != null) {
                    payVo.setAccountDriverBean(findAccountDriverVo.getData());
                }
            }
            //获取乘客
            PassengerVo passengerVo = passengerService.selInfo(orderDto.getPassengerUuid()).getData();
            if (passengerVo == null) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到乘客信息");
            }
            payVo.setPassengerVo(passengerVo);
            //获取乘客账户
            ResponseData<SysPassengerAccountVo> findAccountPassengerVo = sysAccountPassengerService.findAccountPassengerVo(
                    MapUtils.build("uuid", orderDto.getPassengerUuid()));
            if (findAccountPassengerVo.isSuccess() && findAccountPassengerVo.getData() != null) {
                payVo.setAccountPassengerBean(findAccountPassengerVo.getData());
            }
        }

        //充值
        if (payVo.getPayPurpose() == OrderConstant.PAY_PURPOSE_RECHARGE_ACCOUNT) {
            PassengerRechargeDto passengerRechargeDto = passengerRechargeService.findPassengerRechargeDto(
                    MapUtils.build("uuid", payVo.getRechargeUuid())).getData();
            if (passengerRechargeDto == null) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到充值面额信息");
            }
            payVo.setPassengerRechargeDto(passengerRechargeDto);
            //初始化充值订单信息
            OrderRechargeDto orderRechargeDto = new OrderRechargeDto();
            orderRechargeDto.setUuid(StringUtils.buildUUID());
            orderRechargeDto.setAppid(payVo.getAppid());
            orderRechargeDto.setCreateBy(payVo.getUserUuid());
            orderRechargeDto.setAccountUuid(payVo.getUserUuid());
            orderRechargeDto.setPaySide(payVo.getPaySide());
            orderRechargeDto.setPayType(payVo.getPayType());
            orderRechargeDto.setTemplateUuid(payVo.getPassengerRechargeDto().getUuid());
            orderRechargeDto.setRechargeAmount(BigDecimal.valueOf(payVo.getPassengerRechargeDto().getMoney()));
            orderRechargeDto.setGiftAmount(BigDecimal.valueOf(payVo.getPassengerRechargeDto().getGift()));
            orderRechargeDto.setStatus(OrderRechargeDto.STATUS_PREPAY);
            //记录充值城市
            PassengerRechargeCityDto passengerRechargeCityDto = passengerRechargeCityService.get(payVo.getRechargeUuid()).getData();
            if (passengerRechargeCityDto != null) {
                orderRechargeDto.setRechargeCityid(passengerRechargeCityDto.getCityUuid());
            }
            if (payVo.getPaySide() == CommonConstant.PASSENGER) {
                PassengerVo passengerVo = passengerService.selInfo(payVo.getUserUuid()).getData();
                if (passengerVo == null) {
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到乘客信息");
                }
                payVo.setPassengerVo(passengerVo);
                orderRechargeDto.setMobile(payVo.getPassengerVo().getMobile());
            }
            if (payVo.getPaySide() == CommonConstant.DRIVER) {
                DriverVo driverVo = driverService.selInfo(payVo.getUserUuid()).getData();
                if (driverVo == null) {
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到司机信息");
                }
                payVo.setDriverVo(driverVo);
                orderRechargeDto.setMobile(payVo.getDriverVo().getMobile());
            }
            //创建充值订单
            ResponseData<Boolean> responseData = orderRechargeService.add(orderRechargeDto);
            if (!responseData.isSuccess() || Boolean.FALSE.equals(responseData.getData())) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "创建充值订单失败");
            }
            payVo.setOrderRechargeUuid(orderRechargeDto.getUuid());
            payVo.setOrderUuid(orderRechargeDto.getUuid());
            logger.info("{}--创建充值订单成功:{}", payVo.getDescription(), orderRechargeDto.getUuid());
        }
        return ResponseData.buildSuccessResponse("通过订单状态校验", payVo);
    }

    /**
     * 回调业务逻辑校验
     *
     * @return
     */
    private ResponseData<Boolean> validateBusinessCallback(PayVo payVo, String userUuid) {
        //支付车费
        if (payVo.getPayPurpose() == OrderConstant.PAY_PURPOSE_CHARGE_FARE) {
            //订单状态校验--获取数据最新订单情况
            OrderDto orderDto = orderService.get(payVo.getOrderUuid()).getData();
            if (orderDto == null) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到订单信息");
            }
            if (Constants.ORDER_PAID_SUB_STATUS.contains(orderDto.getSubStatus())) {
                return ResponseData.buildErrorResponse(ERR_CODE_HAD_PAID.getCode(), ERR_CODE_HAD_PAID.getMsg());
            }
            if (!Constants.ORDER_PREPAY_SUB_STATUS.contains(orderDto.getSubStatus())) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "订单状态判定订单状态异常，请联系管理员");
            }
            //操作人校验 -- 第三方回调跳过此校验
            if (StringUtils.isNotEmpty(userUuid)) {
                if (payVo.getPaySide() == CommonConstant.PASSENGER) {
                    if (!userUuid.equals(orderDto.getPassengerUuid())) {
                        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "非发单乘客无操作权限");
                    }
                }
                if (payVo.getPaySide() == CommonConstant.DRIVER) {
                    if (!userUuid.equals(orderDto.getActualDriverUuid())) {
                        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "非实际接单司机无操作权限");
                    }
                }
            }
        }
        //充值
        if (payVo.getPayPurpose() == OrderConstant.PAY_PURPOSE_RECHARGE_ACCOUNT) {
            //订单状态校验--获取数据最新订单情况
            OrderRechargeDto orderRechargeDto = orderRechargeService.get(MapUtils.build("uuid", payVo.getOrderUuid())).getData();
            if (orderRechargeDto == null) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到充值订单信息");
            }
            if (orderRechargeDto.getStatus() == OrderRechargeDto.STATUS_PAID) {
                return ResponseData.buildErrorResponse(ERR_CODE_HAD_PAID.getCode(), ERR_CODE_HAD_PAID.getMsg());
            }
        }
        return ResponseData.buildSuccessResponse("通过订单状态校验", Boolean.TRUE);
    }


    /**
     * 回调验验签
     */
    private ResponseData<Boolean> callbackValidateSign(PayVo payVo, Map<String, String> map, String key) {
        String sign = map.get("sign");
        map.remove("sign");
        map.remove("sign_type");

        if (payVo.getPayType() == OrderConstant.PAY_TYPE_TENPAY) {
            return PayVerifySignUtils.validateSignTenPay(map, key, sign) ? ResponseData.buildSuccessResponse("通过MD5验签", Boolean.TRUE) : ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "MD5验签失败");
        }
        if (payVo.getPayType() == OrderConstant.PAY_TYPE_ALIPAY) {
            logger.info("8888888888:{}",PayVerifySignUtils.validateSignAliPay(map, key, sign));
            return PayVerifySignUtils.validateSignAliPay(map, key, sign) ? ResponseData.buildSuccessResponse("通过RSA验签", Boolean.TRUE) : ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "RSA验签失败");
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "验签失败--不合法的支付类型");
    }

    /**
     * 回调验证状态
     *
     * @return
     */
    private ResponseData<Boolean> callbackValidateStatus(PayVo payVo, Map<String, String> map) {
        if (payVo.getPayType() == OrderConstant.PAY_TYPE_TENPAY) {
            String returnCode = map.get("return_code");
            String resultCode = map.get("result_code");
            if (returnCode == null || resultCode == null) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "回调状态为空");
            }
            if (!"SUCCESS".equals(returnCode)) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "回调通讯异常--" + map.get("return_msg"));
            }
            if (!"SUCCESS".equals(resultCode)) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "回调结果异常--" + map.get("err_code_des"));
            }
            return ResponseData.buildSuccessResponse("回调状态验证通过", Boolean.TRUE);
        }
        if (payVo.getPayType() == OrderConstant.PAY_TYPE_ALIPAY) {
            String tradeStatus = map.get("trade_status");
            if (tradeStatus == null || !"TRADE_SUCCESS".equals(tradeStatus)) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "回调状态异常--" + tradeStatus);
            }
            return ResponseData.buildSuccessResponse("回调状态验证通过", Boolean.TRUE);
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "验签失败--不合法的支付类型");
    }

    /**
     * 回调获取加密秘钥
     *
     * @return
     */
    private ResponseData<String> callbackGetSignKey(PayVo payBean) {
        if (payBean.getPayType() == OrderConstant.PAY_TYPE_TENPAY) {
            if (payBean.getPaySide() == CommonConstant.PASSENGER) {
                return ResponseData.buildSuccessResponse("获取验签秘钥成功", NacosListener.WXPAY_CONFIG.getPassengerWxAppKey());
            }
            if (payBean.getPaySide() == CommonConstant.PASSENGER_PULBIC || payBean.getPaySide() == CommonConstant.PASSENGER_H5) {
                return ResponseData.buildSuccessResponse("获取验签秘钥成功", NacosListener.WXPAY_CONFIG.getPassengerPublicWxAppKey());
            }
            if (payBean.getPaySide() == CommonConstant.PASSENGER_APPLET) {
                return ResponseData.buildSuccessResponse("获取验签秘钥成功", NacosListener.WXPAY_CONFIG.getPassengerAppletWxAppKey());
            }
            if (payBean.getPaySide() == CommonConstant.DRIVER) {
                if (payBean.getOrderDto().getTypeTrip() == 1) {
                    return ResponseData.buildSuccessResponse("获取验签秘钥成功", NacosListener.WXPAY_CONFIG.getDriverWxAppKey());
                }
                //快车、专车用相同秘钥
                if (Constants.APP_TYPE_SPECIAL.contains(payBean.getOrderDto().getTypeTrip())) {
                    return ResponseData.buildSuccessResponse("获取验签秘钥成功", NacosListener.WXPAY_CONFIG.getDriverWxAppKey());
                }
            }
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取验签秘钥失败--不合法的业务类型");
        }
        if (payBean.getPayType() == OrderConstant.PAY_TYPE_ALIPAY) {
//            return ResponseData.buildSuccessResponse("获取验签秘钥成功", NacosListener.ALIPAY_CONFIG.getOpenBizPublicKey());
            return ResponseData.buildSuccessResponse("获取验签秘钥成功", NacosListener.ALIPAY_CONFIG.getPayPublickey());
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取验签秘钥失败--不合法的支付类型");
    }

    /**
     * 清除支付缓存
     */
    private void removeLock(PayVo payBean) {
        logger.info("{}--尝试清除入口缓存锁", payBean.getDescription());
        if (redisCacheService.hasKey(Constants.ORDER_CACHE_KEY + payBean.getOrderUuid())) {
            redisCacheService.delete(Constants.ORDER_CACHE_KEY + payBean.getOrderUuid());
            logger.info("{}--清除入口缓存锁--", payBean.getDescription());
        } else {
            logger.info("{}--入口缓存锁不存在", payBean.getDescription());
        }
    }


    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ResponseData<Boolean> receiveCash(String orderUuid, String uploadText) {
        OrderDto updateOrderDto = orderService.get(orderUuid).getData();
        if (updateOrderDto != null) {
            Date date = new Date();
            //更新订单表
            updateOrderDto.setMainStatus(OrderConstant.ORDER_MAIN_STATUS_PAYED);
            updateOrderDto.setSubStatus(OrderConstant.ORDER_STATUS_COMPLETE);
            updateOrderDto.setPayPurpose(OrderConstant.PAY_PURPOSE_CHARGE_FARE);
            updateOrderDto.setPaySide(CommonConstant.PASSENGER);
            updateOrderDto.setPayType(OrderConstant.PAY_TYPE_CASH);
            updateOrderDto.setPayStatus(Constants.ORDER_PAY_STATUS_PAYED);
            updateOrderDto.setPayTime(date);
            OrderHelper.saveOrUpdate(updateOrderDto);

            //现金支付把起步价和行程费用设为null
            Map<String, Object> searchMap = new HashMap<>(1);
            searchMap.put("orderUuid", orderUuid);
            OrderFareDto orderFareDto = orderFareService.get(searchMap).getData();
            if (orderFareDto != null) {
                //司机支付，说明都是收现
                orderFareDto.setPayType(OrderConstant.PAY_TYPE_CASH);
                orderFareDto.setActualFare(orderFareDto.getTotalFare());
                orderFareDto.setPayTime(date);
                orderFareService.saveOrUpdate(orderFareDto);
            }

            //上传长连接点
            UploadLocationMessage uploadLocationMessage = null;
            try {
                uploadLocationMessage = JsonUtils.readValue(uploadText, UploadLocationMessage.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
            uploadLocationService.uploadDriverLocation(uploadLocationMessage);
            //判断是否乘客完成首单 判断邀请者是否符合领取奖励条件
            PassengerVo passengerVo = passengerService.selInfo(updateOrderDto.getPassengerUuid()).getData();
            passengerVo.setOrderCount(passengerVo.getOrderCount() == null ? 1 : passengerVo.getOrderCount() + 1);
            if (passengerVo.getOrderCount() == 1) {
                PayVo payVo = new PayVo();
                payVo.setPassengerVo(passengerVo);
                PayProcessor processor = (PassengerGiftProcessor) SpringContextHolder.getBean("passengerGiftProcessor");
                processor.process(payVo);
            }
            //推乘客
            Map<String, Object> pushPassengerMap = MapUtils.build();
            pushPassengerMap.put("orderUuid", orderUuid);
            pushPassengerMap.put("title", "收到支付信息");
            pushPassengerMap.put("content", "司机已收现");
            pushPassengerMap.put("typeModule", updateOrderDto.getTypeModule());
            PushContent pushPassengerContent = PushContent.newInstance4Pas(updateOrderDto.getAppid(), PushContent.ORDER_DRIVER_HELP_PAYED_SUCCESS, pushPassengerMap);
            pushService.sendMessage(updateOrderDto.getPassengerUuid(), pushPassengerContent);
        }
        return ResponseData.buildSuccessResponse("收取现金成功", Boolean.TRUE);
    }

    @Override
    public ResponseData<Boolean> checkPay(String orderUuid) {
        PayVo payVo;
        OrderDto updateOrderDto = new OrderDto();
        updateOrderDto.setUuid(orderUuid);
        Map<String, Object> map = MapUtils.build(3);
        map.put("orderUuid", orderUuid);
        //查询已支付的预支付信息
        map.put("status", 1);
        List<FinancePrepayDto> financePrepayList = financePrepayService.list(map).getData();
        if (CollectionUtils.isNotEmpty(financePrepayList)) {
            //更新订单状态
            try {
                FinancePrepayDto financePrepay = financePrepayList.get(0);
                payVo = JsonUtils.readValue(financePrepay.getParams(), PayVo.class);
                updateOrderDto.setMainStatus(OrderConstant.ORDER_MAIN_STATUS_PAYED);
                updateOrderDto.setSubStatus(OrderConstant.ORDER_STATUS_COMPLETE);
                updateOrderDto.setPayPurpose(payVo.getPayPurpose());
                updateOrderDto.setPaySide(payVo.getPaySide());
                updateOrderDto.setPayType(payVo.getPayType());
                updateOrderDto.setPayTime(new Date());
                updateOrderDto.setUpdateOn(new Date());
                orderService.edit(updateOrderDto);
                //更新订单价格表
                OrderFareDto updateOrderFareDto = new OrderFareDto();
                updateOrderFareDto.setUuid(payVo.getOrderFareDto().getUuid());
                updateOrderFareDto.setActualFare(payVo.getActualFare().doubleValue());
                updateOrderFareDto.setCouponFare(payVo.getActualDeductible().doubleValue());
                updateOrderFareDto.setPayType(payVo.getPayType());
                updateOrderFareDto.setPayTime(new Date());
                updateOrderFareDto.setUpdateOn(new Date());
                orderFareService.edit(updateOrderFareDto);
                //更新优惠券信息
                PassengerCouponDto updatePassengerCouponDto = new PassengerCouponDto();
                updatePassengerCouponDto.setUuid(payVo.getPassengerCouponUuid());
                updatePassengerCouponDto.setMoney(payVo.getActualDeductible().doubleValue());
                updatePassengerCouponDto.setOrderUuid(payVo.getOrderUuid());
                //已使用
                updatePassengerCouponDto.setStatus(PassengerConstant.COUPON_STATUS_USERED);
                passengerCouponService.edit(updatePassengerCouponDto);

                //计算抽成
                commissionProcessor.process(payVo);

                return ResponseData.buildSuccessResponse("预支付已完成", Boolean.TRUE);
            } catch (IOException e) {
                e.printStackTrace();
                logger.error("预支付异常，orderUuid:{}", orderUuid);
            }
        }
        //查询未支付的预支付信息
        map.put("status", 0);
        List<FinancePrepayDto> financePrepayDtos = financePrepayService.list(map).getData();
        if (financePrepayDtos == null) {
            return ResponseData.buildErrorResponse(10001, "无预支付信息");
        }
        for (FinancePrepayDto financePrepay : financePrepayDtos) {
            //微信
            if (financePrepay.getType() == OrderConstant.PAY_TYPE_TENPAY) {
                try {
                    payVo = JsonUtils.readValue(financePrepay.getParams(), PayVo.class);
                    ResponseData<Map<String, String>> selTenPayData = PayDataBuilder.selTenPayData(payVo);
                    if (selTenPayData.isSuccess()) {
                        //更新订单状态
                        updateOrderDto.setMainStatus(OrderConstant.ORDER_MAIN_STATUS_PAYED);
                        updateOrderDto.setSubStatus(OrderConstant.ORDER_STATUS_COMPLETE);
                        updateOrderDto.setPayPurpose(payVo.getPayPurpose());
                        updateOrderDto.setPaySide(payVo.getPaySide());
                        updateOrderDto.setPayType(payVo.getPayType());
                        updateOrderDto.setPayTime(new Date());
                        updateOrderDto.setUpdateOn(new Date());
                        orderService.edit(updateOrderDto);
                        //更新订单价格表
                        OrderFareDto updateOrderFareDto = new OrderFareDto();
                        updateOrderFareDto.setUuid(payVo.getOrderFareDto().getUuid());
                        updateOrderFareDto.setActualFare(payVo.getActualFare().doubleValue());
                        updateOrderFareDto.setCouponFare(payVo.getActualDeductible().doubleValue());
                        updateOrderFareDto.setPayType(payVo.getPayType());
                        updateOrderFareDto.setPayTime(new Date());
                        updateOrderFareDto.setUpdateOn(new Date());
                        orderFareService.edit(updateOrderFareDto);
                        //更新优惠券信息
                        PassengerCouponDto updatePassengerCouponDto = new PassengerCouponDto();
                        updatePassengerCouponDto.setUuid(payVo.getPassengerCouponUuid());
                        updatePassengerCouponDto.setMoney(payVo.getActualDeductible().doubleValue());
                        updatePassengerCouponDto.setOrderUuid(payVo.getOrderUuid());
                        //已使用
                        updatePassengerCouponDto.setStatus(PassengerConstant.COUPON_STATUS_USERED);
                        passengerCouponService.edit(updatePassengerCouponDto);

                        //计算抽成
                        commissionProcessor.process(payVo);

                        //司机收入
                        return ResponseData.buildSuccessResponse("微信已支付", Boolean.TRUE);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error("微信支付异常，orderUuid:{}", orderUuid);
                }
            }
            //支付宝
            if (financePrepay.getType() == OrderConstant.PAY_TYPE_ALIPAY) {
                try {
                    payVo = JsonUtils.readValue(financePrepay.getParams(), PayVo.class);
                    ResponseData<String> selAliPayData = PayDataBuilder.selAliPayData(payVo);
                    if (selAliPayData.isSuccess()) {
                        //更新订单状态
                        updateOrderDto.setMainStatus(OrderConstant.ORDER_MAIN_STATUS_PAYED);
                        updateOrderDto.setSubStatus(OrderConstant.ORDER_STATUS_COMPLETE);
                        updateOrderDto.setPayPurpose(payVo.getPayPurpose());
                        updateOrderDto.setPaySide(payVo.getPaySide());
                        updateOrderDto.setPayType(payVo.getPayType());
                        updateOrderDto.setPayTime(new Date());
                        updateOrderDto.setUpdateOn(new Date());
                        orderService.edit(updateOrderDto);
                        //更新订单价格表
                        OrderFareDto updateOrderFareDto = new OrderFareDto();
                        updateOrderFareDto.setUuid(payVo.getOrderFareDto().getUuid());
                        updateOrderFareDto.setActualFare(payVo.getActualFare().doubleValue());
                        updateOrderFareDto.setCouponFare(payVo.getActualDeductible().doubleValue());
                        updateOrderFareDto.setPayType(payVo.getPayType());
                        updateOrderFareDto.setPayTime(new Date());
                        updateOrderFareDto.setUpdateOn(new Date());
                        orderFareService.edit(updateOrderFareDto);
                        //更新优惠券信息
                        PassengerCouponDto updatePassengerCouponDto = new PassengerCouponDto();
                        updatePassengerCouponDto.setUuid(payVo.getPassengerCouponUuid());
                        updatePassengerCouponDto.setMoney(payVo.getActualDeductible().doubleValue());
                        updatePassengerCouponDto.setOrderUuid(payVo.getOrderUuid());
                        //已使用
                        updatePassengerCouponDto.setStatus(PassengerConstant.COUPON_STATUS_USERED);
                        passengerCouponService.edit(updatePassengerCouponDto);

                        //计算抽成
                        commissionProcessor.process(payVo);

                        //司机收入
                        return ResponseData.buildSuccessResponse("支付宝已支付", Boolean.TRUE);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error("支付宝支付异常，orderUuid:{}", orderUuid);
                }
            }
        }
        return ResponseData.buildErrorResponse(10002, "预支付未完成");
    }

    @Override
    public ResponseData<Void> removePayCache(String orderUuid) {
        String cacheKey = Constants.ORDER_CACHE_KEY + orderUuid;
        logger.info("订单：{} 客户端调用--尝试清除入口缓存锁", orderUuid);
        if (redisCacheService.hasKey(cacheKey)) {
            redisCacheService.delete(cacheKey);
        } else {
            logger.info("订单：{} 客户端调用--入口缓存锁不存在", orderUuid);
        }
        return ResponseData.buildSuccessResponse("操作完成", null);
    }


    @Override
    public ResponseData<Boolean> repairData(String serialNumber) {
        FinancePrepayDto financePrepayDto = financePrepayService.get(MapUtils.build("serialNumber", serialNumber)).getData();
        if (financePrepayDto == null) {
            logger.info("--流水号[" + serialNumber + "]--获取不到预支付信息");
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到系统内部预支付信息");
        }

        PayVo payVo = null;
        try {
            payVo = JsonUtils.readValue(financePrepayDto.getParams(), PayVo.class);
            PayLogBuilder.prependLog(payVo, "[第三方回调]");
        } catch (IOException e) {
            e.printStackTrace();
        }
        PayProcessorFactory.processCommon(payVo);
        PayProcessorFactory.processPassengerGift(payVo);
        return ResponseData.buildSuccessResponse(Boolean.TRUE);
    }
}
